package cn.highedu.spring;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan("cn.highedu.spring")
public class ScopeTest {
    ApplicationContext context = null;
    @BeforeEach
    public void createContext() {
        context = new AnnotationConfigApplicationContext(ScopeTest.class);
    }

    @Test
    public void test1() {
        /**
         * 被Spring管理的对象一定要有默认的构造方法
         * 被Spring管理的对象默认都是单例的(Scope="singleton")
         * 单例的对象在Spring容器初始化的时候创建该对象
         * 单例的对象会被Spring容器一直管理
         */
        SingletonBean bean1 = context.getBean(SingletonBean.class);
        SingletonBean bean2 = context.getBean(SingletonBean.class);
        System.out.println(bean1 == bean2);

        /**
         * 被Spring管理的对象如果设置为了原型模式(Scope="prototype")
         * 每次获取的对象都是一个新的对象
         * 原型模式的对象在获取的时候Spring容器才会创建 并且不会交由Spring容器管理
         * 一旦Java的GC(垃圾回收机制)运行, 有可能该对象会被回收
         */
        PrototypeBean bean3 = context.getBean(PrototypeBean.class);
        PrototypeBean bean4 = context.getBean(PrototypeBean.class);
        System.out.println(bean3 == bean4);

        /**
         * 最佳实践:
         * 当一个类中没有属性 也就意味着该类的对象不会发生状态变化 这个类就可以设置为单例模式
         * 当一个类有属性 但是属性是单例的 该类的对象也不会发生状态变化 这个类也可以设置为单例的
         * 如果一类中有属性 属性不是单例的 这个类就不能设置为单例的
         */
    }
}
